iT邦幫忙

2021 iThome 鐵人賽

DAY 2
0
Software Development

猴子都寫得出來的 RISC-V CPU Emulator系列 第 23

RISC-V: R-type 位元運算指令

  • 分享至 

  • xImage
  •  

今天一樣是簡單的 AND、OR、XOR指令實作,
多出來的時間就來還摸索期留下來的債,
讓整個專案變得更完整和容易維護,
這次補上 JUMP/BRANCH Exception 和 LOAD/STORE Exception。

R-type

指令格式如下:

|31     25|24   20|19   15|14    12|11   7|6       0|
+---------------------------------------------------+
|  func7  |  rs2  |  rs1  | funct3 |  rd  | opcode  |
+---------------------------------------------------+

AND

rd = rs1 & rs2

|31         25|24   20|19   15|14    12|11   7|6       0|
+-------------------------------------------------------+
|   0000000   |  rs2  |  rs1  |  111   |  rd  | 0110011 |
+-------------------------------------------------------+

OR

rd = rs1 | rs2

|31         25|24   20|19   15|14    12|11   7|6       0|
+-------------------------------------------------------+
|   0000000   |  rs2  |  rs1  |  110   |  rd  | 0110011 |
+-------------------------------------------------------+

XOR

rd = rs1 ^ rs2

|31         25|24   20|19   15|14    12|11   7|6       0|
+-------------------------------------------------------+
|   0000000   |  rs2  |  rs1  |  100   |  rd  | 0110011 |
+-------------------------------------------------------+

實際程式

github 頁面 Tag: ITDay23

JUMP/BRANCH Exception 的條件會取決於是否支援 Compress Extension,
詳細內容可以看前面的文章
這次先在 Executor 做了一個簡單的判斷和處理,
未來實做 CSR 再改掉。

LOAD/STORE Exception 的條件會取決於存取的大小和 EEI 的設計,
詳細內容在前面的文章有提到,
因為目前沒有實做其他裝置與判斷機制,
這邊先當作 address misalignment 處理。

//executor.cpp
...
#define INSTRUCTION_ALIGNMENT 4
#define LOAD_STORE_ALIGNMENT_W 4
#define LOAD_STORE_ALIGNMENT_HW 4

bool isAlignment(uint32_t address, unsigned int baseNumber)
{
	if(0 == address % baseNumber) {
		return true;
	} else {
		return false;
	}
}
...
void EXECUTOR::LH_E()
{
	auto rs1 = instruction_decoder->get_rs1();
	auto rd = instruction_decoder->get_rd();
	auto addr = register_file->get_value_integer(rs1) + (uint32_t) instruction_decoder->get_imm(31, 20);

	if(!isAlignment(addr, LOAD_STORE_ALIGNMENT_HW)) {
		cpu->raise_exception(CPU_INTERFACE::LOAD_ADDRESS_MISALIGNED_EXCEPTION_CAUSE);
	}
...
void EXECUTOR::JALR_E()
{
	auto offset = instruction_decoder->get_imm(31, 20);
	auto rs1 = instruction_decoder->get_rs1();
	auto rd = instruction_decoder->get_rd();
	auto addr = (register_file->get_value_integer(rs1) + offset) & ~0x1;

	if(!isAlignment(addr, INSTRUCTION_ALIGNMENT)) {
		cpu->raise_exception(CPU_INTERFACE::INSTRUCTION_ADDRESS_MISALIGNED_EXCEPTION_CAUSE);
	}
...

指令部分相對單純,
這次用 AND 當範例,實作如下:

//executor.cpp
...
		case INSTRUCTION_DECODER_INTERFACE::AND_FN3:
			AND_E();
			//do not check FN7 for readibility, refactor in future
			break;
...
void EXECUTOR::AND_E()
{
	auto rd = instruction_decoder->get_rd();
	auto rs1 = instruction_decoder->get_rs1();
	auto rs2 = instruction_decoder->get_rs2();

	auto value = register_file->get_value_integer(rs1) & register_file->get_value_integer(rs2);
	register_file->set_value_integer(rd, value);
}
//instructionDecodetInterface.h
...
		AND_FN3 = 0b111,
...
		AND_FN7 = 0b0000000,
...

上一篇
RISC-V: R-type 算術指令
下一篇
RISC-V: R-type 小於指令
系列文
猴子都寫得出來的 RISC-V CPU Emulator31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言